package com.idega.jackrabbit.security; import java.security.Principal; import java.util.HashMap; import java.util.Map; import javax.jcr.Credentials; import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.FailedLoginException; import javax.security.auth.login.LoginException; import org.apache.jackrabbit.api.security.user.AuthorizableExistsException; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.jackrabbit.core.SessionImpl; import org.apache.jackrabbit.core.security.SecurityConstants; import org.apache.jackrabbit.core.security.authentication.DefaultLoginModule; import org.springframework.beans.factory.annotation.Autowired; import com.idega.core.accesscontrol.business.LoginDBHandler; import com.idega.core.accesscontrol.data.LoginTable; import com.idega.jackrabbit.JackrabbitConstants; import com.idega.util.StringUtil; import com.idega.util.expression.ELUtil; /** * Class, responsible for handling logins into repository. * * @author valdas * */ public class RepositoryLoginModule extends DefaultLoginModule { @Autowired private JackrabbitSecurityHelper securityHelper; private UserManager userManager; private Map<String, String> ids = new HashMap<String, String>(); JackrabbitSecurityHelper getSecurityHelper() { if (securityHelper == null) { ELUtil.getInstance().autowire(this); } return securityHelper; } @Override public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { if (adminId == null || SecurityConstants.ADMIN_ID.equals(adminId)) { try { adminId = getSecurityHelper().getSuperAdminId(); } catch (RepositoryException e) { e.printStackTrace(); } } super.initialize(subject, callbackHandler, sharedState, options); } @Override protected void doInit(CallbackHandler callbackHandler, Session session, @SuppressWarnings("rawtypes") Map options) throws LoginException { super.doInit(callbackHandler, session, options); try { userManager = ((SessionImpl) session).getUserManager(); } catch (RepositoryException e) { throw new LoginException("Unable to initialize LoginModule: " + e.getMessage()); } } private boolean createLogin(String user, String password) { try { return userManager.createUser(user, password) != null; } catch (AuthorizableExistsException e) { e.printStackTrace(); return true; } catch (RepositoryException e) { e.printStackTrace(); } return false; } @Override public boolean login() throws LoginException { Credentials credentials = getCredentials(); if (!(credentials instanceof SimpleCredentials)) { return super.login(); } Principal principal = getPrincipal(credentials); if (principal == null) { SimpleCredentials cred = (SimpleCredentials) credentials; if (!createLogin(getUserID(credentials), String.valueOf(cred.getPassword()))) { return false; } } return super.login(); } @Override protected boolean authenticate(Principal principal, Credentials credentials) throws FailedLoginException, RepositoryException { String userId = getUserID(credentials); if (StringUtil.isEmpty(userId)) { return super.authenticate(principal, credentials); } if (userId.equals(getAdminId())) { return true; // Administrator user has all rights } if (credentials instanceof SimpleCredentials) { credentials = new SimpleCredentials(userId, ((SimpleCredentials) credentials).getPassword()); } return super.authenticate(principal, credentials); } @Override protected String getUserID(Credentials credentials) { if (!(credentials instanceof SimpleCredentials)) { return super.getUserID(credentials); } SimpleCredentials cred = (SimpleCredentials) credentials; String id = cred.getUserID(); if (id == null) { return super.getUserID(credentials); } String key = id + String.valueOf(cred.getPassword()); String userId = ids.get(key); if (userId != null) { return userId; } boolean realId = false; Object realIdAttr = cred.getAttribute(JackrabbitConstants.REAL_USER_ID_USED); if (realIdAttr instanceof String) { realId = Boolean.valueOf((String) realIdAttr); } if (!realId) { try { LoginTable loginTable = LoginDBHandler.getUserLoginByUserName(id); userId = loginTable == null ? null : String.valueOf(loginTable.getUserId()); } catch (Exception e) { e.printStackTrace(); } } if (userId == null) { userId = super.getUserID(credentials); } if (userId != null) { ids.put(key, userId); } return userId; } }